package club.mrxiao.gps.service.impl;

import club.mrxiao.gps.exception.RedisConnectException;
import club.mrxiao.gps.function.JedisExecutor;
import club.mrxiao.gps.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Set;

/**
 * redis服务接口实现
 * @author xiaoyu
 */
@Service
public class RedisServiceImpl implements RedisService {

    private final JedisPool jedisPool;

    @Autowired
    public RedisServiceImpl(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    private static final String EXPX = "PX";
    private static final String NXXX = "NX";

    /**
     * 处理 jedis请求
     *
     * @param j 处理逻辑，通过 lambda行为参数化
     * @return 处理结果
     */
    private <T> T excuteByJedis(JedisExecutor<Jedis, T> j) throws RedisConnectException {
        try (Jedis jedis = jedisPool.getResource()) {
            return j.excute(jedis);
        } catch (Exception e) {
            throw new RedisConnectException(e.getMessage());
        }
    }

    @Override
    public String get(String key) throws RedisConnectException {
        return this.excuteByJedis(j -> j.get(key.toLowerCase()));
    }

    @Override
    public void set(String key, String value) throws RedisConnectException {
        this.excuteByJedis(j -> j.set(key.toLowerCase(), value));
    }

    @Override
    public void set(String key, String value, Long milliscends) throws RedisConnectException {
        if(exists(key)){
            del(key);
        }
        this.excuteByJedis(j -> j.set(key.toLowerCase(),value,NXXX,EXPX,milliscends));
    }

    @Override
    public void del(String... key) throws RedisConnectException {
        this.excuteByJedis(j -> j.del(key));
    }

    @Override
    public Boolean exists(String key) throws RedisConnectException {
        return this.excuteByJedis(j -> j.exists(key));
    }

    @Override
    public void zadd(String key, Double score, String member) throws RedisConnectException {
        this.excuteByJedis(j -> j.zadd(key, score, member));
    }

    @Override
    public Set<String> zrange(String key, long min, long max) throws RedisConnectException {
        return this.excuteByJedis(j -> j.zrange(key,min,max));
    }

    @Override
    public void zrem(String key, String... members) throws RedisConnectException {
        this.excuteByJedis(j -> j.zrem(key, members));
    }
}
